<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>头条猎人们</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        body { font-family: 'Segoe UI', 'PingFang SC', Arial, sans-serif; background: #f6f8fa; margin: 0; }
        .container {
            max-width: 800px;
            margin: 40px auto;
            background: #fff;
            border-radius: 12px;
            box-shadow: 0 2px 16px #0001;
            padding: 32px 24px;
        }
        h1 { text-align: center; color: #222; margin-bottom: 16px; }
        .toolbar {
            display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between; align-items: center; margin-bottom: 24px;
            position: relative;
        }
        .toolbar input[type='text'] { flex: 1; min-width: 180px; padding: 8px 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; }
        .toolbar button { padding: 8px 18px; border: none; border-radius: 6px; background: #0057ff; color: #fff; font-size: 16px; cursor: pointer; transition: background 0.2s; }
        .toolbar button:hover { background: #003fa3; }
        .news-list { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
        @media (max-width: 700px) { .news-list { grid-template-columns: 1fr; } }
        .news-card {
            background: #f9fafb;
            border-radius: 8px;
            box-shadow: 0 1px 4px #0001;
            padding: 18px 16px;
            display: flex;
            flex-direction: column;
            gap: 8px;
            position: relative; /* 关键：为绝对定位的子元素提供参照 */
            min-height: 90px;   /* 适当增加高度，避免内容重叠 */
            padding-bottom: 40px; /* 为摘要按钮留出空间 */
            transition: all 0.3s ease; /* 平滑过渡效果 */
        }
        
        .summary-btn {
            position: absolute;
            bottom: 8px;
            right: 8px;
            width: 24px;
            height: 24px;
            background: #28a745;
            color: white;
            border: none;
            border-radius: 50%;
            cursor: pointer;
            font-size: 12px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.2s;
            opacity: 0.8;
            z-index: 2;
        }
        
        .summary-btn:hover {
            opacity: 1;
            transform: scale(1.1);
        }
        
        .summary-btn.loading {
            background: #ffc107;
            animation: spin 1s linear infinite;
        }
        
        .summary-content {
            background: #e8f5e8;
            border-radius: 6px;
            padding: 12px;
            margin-top: 12px;
            margin-bottom: 8px;
            font-size: 14px;
            line-height: 1.5;
            color: #2c5530;
            border-left: 3px solid #28a745;
            display: none;
            position: relative;
            z-index: 1;
            word-wrap: break-word;
            overflow-wrap: break-word;
        }
        
        .summary-content.show {
            display: block;
        }
        
        /* 关闭摘要按钮 */
        .close-summary-btn {
            position: absolute;
            top: 8px;
            right: 8px;
            width: 16px;
            height: 16px;
            background: rgba(255, 255, 255, 0.9);
            color: #333;
            border: 1px solid #ddd;
            border-radius: 50%;
            cursor: pointer;
            font-size: 10px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.2s;
            opacity: 0.8;
            z-index: 3;
        }
        
        .close-summary-btn:hover {
            opacity: 1;
            transform: scale(1.1);
        }
        
        /* 当摘要显示时，调整新闻卡片的布局 */
        .news-card.with-summary {
            padding-bottom: 60px; /* 为摘要内容留出更多空间 */
        }
        
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        
        .feedback-btn {
            position: absolute;
            bottom: 8px;
            right: 36px;
            width: 24px;
            height: 24px;
            background: rgba(255, 255, 255, 0.9);
            color: #333;
            border: 1px solid #ddd;
            border-radius: 50%;
            cursor: pointer;
            font-size: 12px;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.2s;
            opacity: 0.8;
        }
        
        .feedback-btn:hover {
            opacity: 1;
            transform: scale(1.1);
        }
        
        .feedback-tooltip {
            position: absolute;
            bottom: 30px;
            right: 0;
            background: #333;
            color: white;
            padding: 4px 8px;
            border-radius: 4px;
            font-size: 12px;
            white-space: nowrap;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.2s;
        }
        
        .feedback-btn:hover .feedback-tooltip {
            opacity: 1;
        }
        
        .feedback-modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            display: none;
            align-items: center;
            justify-content: center;
            z-index: 1000;
        }
        
        .feedback-modal.show {
            display: flex;
        }
        
        .feedback-content {
            background: white;
            padding: 30px;
            border-radius: 12px;
            max-width: 400px;
            width: 90%;
            text-align: center;
        }
        
        .feedback-title {
            font-size: 18px;
            font-weight: bold;
            margin-bottom: 20px;
            color: #333;
        }
        
        .feedback-options {
            display: flex;
            flex-direction: column;
            gap: 12px;
        }
        
        .feedback-option {
            padding: 12px 16px;
            border: 2px solid #e0e0e0;
            border-radius: 8px;
            background: white;
            cursor: pointer;
            transition: all 0.2s;
            font-size: 14px;
        }
        
        .feedback-option:hover {
            border-color: #0057ff;
            background: #f8f9ff;
        }
        
        .feedback-option.selected {
            border-color: #0057ff;
            background: #0057ff;
            color: white;
        }
        .news-title { font-size: 18px; font-weight: 600; color: #0057ff; text-decoration: none; line-height: 1.4; }
        .news-title:hover { text-decoration: underline; }
        .news-meta {
            color: #888;
            font-size: 13px;
            margin-top: 4px;
            margin-bottom: 8px;
            /* 使用相对定位，避免遮挡问题 */
        }
        .pagination { display: flex; justify-content: center; align-items: center; gap: 12px; margin: 32px 0 0 0; }
        .pagination button { padding: 6px 16px; border: none; border-radius: 5px; background: #eee; color: #333; font-size: 15px; cursor: pointer; }
        .pagination button.active, .pagination button:active { background: #0057ff; color: #fff; }
        .pagination button:disabled { background: #ddd; color: #aaa; cursor: not-allowed; }
        .update-info { text-align: right; color: #888; font-size: 13px; margin-bottom: 8px; }
        .art-title {
            text-align: center;
            font-size: 2.8em;
            font-weight: bold;
            font-style: italic; /* 斜体 */
            letter-spacing: 0.08em;
            color: #a259ff;
            font-family: 'Segoe UI', 'PingFang SC', Arial, sans-serif;
            margin-bottom: 18px;
            background: linear-gradient(90deg, #a259ff 20%, #6c2eb7 80%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
        }
        .order-btn {
            position: absolute;
            right: 0;
            top: 0;
            margin-left: 0;
            background: #fff;
            color: #0057ff;
            border: 1px solid #0057ff;
            font-weight: bold;
            transition: background 0.2s, color 0.2s;
        }
        .order-btn:hover {
            background: #0057ff;
            color: #fff;
        }
        .title-bar {
            position: relative;
            margin-bottom: 1.5em;
            min-height: 3.2em;
        }
        .title-bar .art-title {
            margin: 0 auto;
            text-align: center;
            position: static;
            display: block;
        }
        .toolbar {
            margin-top: 0.5em;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="title-bar">
            <h1 class="art-title">头条猎人们</h1>
            <button onclick="toggleOrder()" id="orderBtn" class="order-btn">从新到旧</button>
        </div>
        <div class="toolbar">
            <input id="search" type="text" placeholder="搜索新闻标题..." />
            <button onclick="searchNews()">搜索</button>
            <button onclick="updateNews()" id="updateBtn">⟳ 更新</button>
        </div>
        <div class="update-info" id="updateInfo"></div>
        <div class="news-list" id="newsList"></div>
        <div class="pagination" id="pagination"></div>
    </div>
    
    <!-- 反馈模态框 -->
    <div class="feedback-modal" id="feedbackModal">
        <div class="feedback-content">
            <div class="feedback-title">请给出反馈以帮助AI以后为您更好地筛选内容</div>
            <div class="feedback-options">
                <div class="feedback-option" data-type="这个新闻与AI无关">这个新闻与AI无关</div>
                <div class="feedback-option" data-type="标题过于浮夸">标题过于浮夸</div>
                <div class="feedback-option" data-type="实际内容质量低">实际内容质量低</div>
                <div class="feedback-option" data-type="无理由">无理由</div>
            </div>
        </div>
    </div>
    <script>
        let page = 1, size = 20, total = 0, lastUpdate = '';
        let currentQuery = '';
        let order = 'desc'; // 默认从新到旧

        function fetchNews(p = 1, q = '', ord = order) {
            page = p;
            currentQuery = q;
            order = ord;
            document.getElementById('newsList').innerHTML = '加载中...';
            fetch(`/api/titles?page=${page}&size=${size}&q=${encodeURIComponent(q)}&order=${order}`)
                .then(r => r.json())
                .then(data => {
                    // 兼容后端返回格式
                    let news = Array.isArray(data) ? data : (data.data || []);
                    total = data.total_articles || data.length || 0;
                    renderNews(news);
                    renderPagination();
                });
        }

        function renderNews(news) {
            const list = document.getElementById('newsList');
            if (!news.length) {
                list.innerHTML = '<div style="color:#888;text-align:center;">没有找到相关内容</div>';
                return;
            }
            list.innerHTML = '';
            news.forEach(item => {
                const card = document.createElement('div');
                card.className = 'news-card';
                card.innerHTML = `
                    <button class="feedback-btn" onclick="openFeedback('${item.title.replace(/'/g, "\\'")}')" title="不可接受">
                        <span>👎</span>
                        <div class="feedback-tooltip">不可接受</div>
                    </button>
                    <button class="summary-btn" onclick="generateSummary(${item.id}, '${item.title.replace(/'/g, "\\'")}', this)" title="生成摘要">
                        <span>📝</span>
                    </button>
                    <a class="news-title" href="/article?id=${item.id}" target="_blank">${item.title}</a>
                    <div class="news-meta">
                        ${item.source ? item.source.trim() : ''}${item.date ? ' | ' + item.date : ''}
                    </div>
                    <div class="summary-content" id="summary-${item.id}">
                        <button class="close-summary-btn" onclick="closeSummary(${item.id})" title="关闭摘要" style="display: none;">
                            <span>×</span>
                        </button>
                    </div>
                `;
                list.appendChild(card);
            });
        }

        function renderPagination() {
            const pag = document.getElementById('pagination');
            pag.innerHTML = '';
            let totalPages = Math.ceil(total / size) || 1;

            // 首页按钮
            let first = document.createElement('button');
            first.innerText = '首页';
            first.disabled = page <= 1;
            first.onclick = () => fetchNews(1, currentQuery);
            pag.appendChild(first);

            // 上一页
            let prev = document.createElement('button');
            prev.innerText = '上一页';
            prev.disabled = page <= 1;
            prev.onclick = () => fetchNews(page - 1, currentQuery);
            pag.appendChild(prev);

            // 页码信息和跳转输入框
            let info = document.createElement('span');
            info.innerHTML = `第 <input id="pageInput" type="number" min="1" max="${totalPages}" value="${page}" style="width:50px;text-align:center;"> / ${totalPages} 页`;
            pag.appendChild(info);

            // 跳转按钮
            let jump = document.createElement('button');
            jump.innerText = '跳转';
            jump.onclick = () => {
                let val = parseInt(document.getElementById('pageInput').value);
                if (val >= 1 && val <= totalPages) {
                    fetchNews(val, currentQuery);
                } else {
                    alert('请输入有效页码');
                }
            };
            pag.appendChild(jump);

            // 下一页
            let next = document.createElement('button');
            next.innerText = '下一页';
            next.disabled = page >= totalPages;
            next.onclick = () => fetchNews(page + 1, currentQuery);
            pag.appendChild(next);

            // 尾页按钮
            let last = document.createElement('button');
            last.innerText = '尾页';
            last.disabled = page >= totalPages;
            last.onclick = () => fetchNews(totalPages, currentQuery);
            pag.appendChild(last);
        }

        function searchNews() {
            const q = document.getElementById('search').value;
            fetchNews(1, q, order);
        }

        function updateNews() {
            const btn = document.getElementById('updateBtn');
            btn.disabled = true;
            btn.innerText = '正在更新...';
            
            fetch('/api/update', { method: 'POST' })
                .then(r => r.json())
                .then(data => {
                    // 开始轮询更新状态
                    pollUpdateStatus();
                })
                .catch(() => {
                    btn.disabled = false;
                    btn.innerText = '⟳ 更新';
                    alert('更新请求失败，请稍后重试');
                });
        }

        function pollUpdateStatus() {
            const btn = document.getElementById('updateBtn');
            const statusInterval = setInterval(() => {
                fetch('/api/update_status')
                    .then(r => r.json())
                    .then(data => {
                        // 更新按钮文本显示当前状态
                        if (data.status === 'crawling') {
                            btn.innerText = '爬取数据中...';
                            showMessage(data.msg, 'info');
                        } else if (data.status === 'crawling_articles') {
                            btn.innerText = '爬取文章内容中...';
                            showMessage(data.msg, 'info');
                        } else if (data.status === 'analyzing') {
                            btn.innerText = 'AI分析中...';
                            showMessage(data.msg, 'info');
                        } else if (data.status === 'importing') {
                            btn.innerText = '导入数据库中...';
                            showMessage(data.msg, 'info');
                        } else if (data.status === 'running') {
                            btn.innerText = '正在更新...';
                            // 继续轮询
                            return;
                        } else {
                            // 停止轮询
                            clearInterval(statusInterval);
                            btn.disabled = false;
                            btn.innerText = '⟳ 更新';
                            
                            // 根据状态显示不同消息
                            if (data.status === 'success') {
                                document.getElementById('updateInfo').innerText = '上次更新：' + (new Date()).toLocaleString();
                                fetchNews(1, currentQuery);
                                showMessage(data.msg, 'success');
                            } else if (data.status === 'already_latest') {
                                showMessage(data.msg, 'info');
                            } else if (data.status === 'failed') {
                                showMessage(data.msg, 'error');
                            } else {
                                showMessage(data.msg, 'warning');
                            }
                        }
                    })
                    .catch(() => {
                        clearInterval(statusInterval);
                        btn.disabled = false;
                        btn.innerText = '⟳ 更新';
                        showMessage('获取更新状态失败', 'error');
                    });
            }, 2000); // 每2秒检查一次状态
        }

        function showMessage(message, type) {
            // 创建消息提示框
            const messageDiv = document.createElement('div');
            messageDiv.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                padding: 15px 20px;
                border-radius: 8px;
                color: white;
                font-weight: bold;
                z-index: 1000;
                max-width: 300px;
                word-wrap: break-word;
                box-shadow: 0 4px 12px rgba(0,0,0,0.3);
                animation: slideIn 0.3s ease-out;
            `;
            
            // 根据类型设置颜色
            if (type === 'success') {
                messageDiv.style.backgroundColor = '#28a745';
            } else if (type === 'error') {
                messageDiv.style.backgroundColor = '#dc3545';
            } else if (type === 'info') {
                messageDiv.style.backgroundColor = '#17a2b8';
            } else if (type === 'warning') {
                messageDiv.style.backgroundColor = '#ffc107';
                messageDiv.style.color = '#212529';
            }
            
            messageDiv.textContent = message;
            document.body.appendChild(messageDiv);
            
            // 3秒后自动移除
            setTimeout(() => {
                messageDiv.style.animation = 'slideOut 0.3s ease-in';
                setTimeout(() => {
                    if (messageDiv.parentNode) {
                        messageDiv.parentNode.removeChild(messageDiv);
                    }
                }, 300);
            }, 3000);
        }

        // 添加CSS动画
        const style = document.createElement('style');
        style.textContent = `
            @keyframes slideIn {
                from { transform: translateX(100%); opacity: 0; }
                to { transform: translateX(0); opacity: 1; }
            }
            @keyframes slideOut {
                from { transform: translateX(0); opacity: 1; }
                to { transform: translateX(100%); opacity: 0; }
            }
        `;
        document.head.appendChild(style);

        function toggleOrder() {
            order = (order === 'asc') ? 'desc' : 'asc';
            document.getElementById('orderBtn').innerText = order === 'asc' ? '从旧到新' : '从新到旧';
            fetchNews(1, currentQuery, order);
        }

        // 反馈相关变量
        let currentFeedbackTitle = '';
        
        // 打开反馈模态框
        function openFeedback(title) {
            currentFeedbackTitle = title;
            document.getElementById('feedbackModal').classList.add('show');
            
            // 重置选项状态
            document.querySelectorAll('.feedback-option').forEach(option => {
                option.classList.remove('selected');
            });
        }
        
        // 关闭反馈模态框
        function closeFeedback() {
            document.getElementById('feedbackModal').classList.remove('show');
            currentFeedbackTitle = '';
        }
        
        // 选择反馈选项
        function selectFeedbackOption(element) {
            // 移除其他选项的选中状态
            document.querySelectorAll('.feedback-option').forEach(option => {
                option.classList.remove('selected');
            });
            
            // 选中当前选项
            element.classList.add('selected');
        }
        
        // 提交反馈
        function submitFeedback() {
            const selectedOption = document.querySelector('.feedback-option.selected');
            if (!selectedOption) {
                alert('请选择一个反馈选项');
                return;
            }
            
            const feedbackType = selectedOption.getAttribute('data-type');
            
            fetch('/api/feedback', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    title: currentFeedbackTitle,
                    feedback_type: feedbackType
                })
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    showMessage('反馈提交成功！', 'success');
                    closeFeedback();
                } else {
                    showMessage('反馈提交失败：' + data.error, 'error');
                }
            })
            .catch(error => {
                showMessage('网络错误，请稍后重试', 'error');
            });
        }
        
        // 绑定反馈选项点击事件
        document.addEventListener('DOMContentLoaded', function() {
            document.querySelectorAll('.feedback-option').forEach(option => {
                option.addEventListener('click', function() {
                    selectFeedbackOption(this);
                });
            });
            
            // 点击模态框外部关闭
            document.getElementById('feedbackModal').addEventListener('click', function(e) {
                if (e.target === this) {
                    closeFeedback();
                }
            });
            
            // 添加提交按钮到模态框
            const feedbackContent = document.querySelector('.feedback-content');
            const submitBtn = document.createElement('button');
            submitBtn.textContent = '提交反馈';
            submitBtn.style.cssText = `
                margin-top: 20px;
                padding: 10px 20px;
                background: #0057ff;
                color: white;
                border: none;
                border-radius: 6px;
                cursor: pointer;
                font-size: 14px;
            `;
            submitBtn.onclick = submitFeedback;
            feedbackContent.appendChild(submitBtn);
        });
        
        // 生成摘要函数
        function generateSummary(articleId, title, button) {
            // 防止重复点击
            if (button.classList.contains('loading')) {
                return;
            }
            
            const summaryContent = document.getElementById(`summary-${articleId}`);
            
            // 显示加载状态
            button.classList.add('loading');
            button.innerHTML = '<span>⏳</span>';
            summaryContent.innerHTML = '';
            summaryContent.classList.remove('show');
            
            // 移除新闻卡片的摘要样式
            const newsCard = summaryContent.closest('.news-card');
            if (newsCard) {
                newsCard.classList.remove('with-summary');
            }
            
            // 发送流式请求
            fetch('/api/summary/stream', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    article_id: articleId,
                    title: title
                })
            })
            .then(response => {
                if (!response.ok) {
                    throw new Error('网络请求失败');
                }
                
                const reader = response.body.getReader();
                const decoder = new TextDecoder();
                let summary = '';
                
                function readStream() {
                    return reader.read().then(({ done, value }) => {
                        if (done) {
                            // 完成摘要生成处理
                            button.classList.remove('loading');
                            button.innerHTML = '<span>📝</span>';
                            return;
                        }
                        
                        const chunk = decoder.decode(value);
                        const lines = chunk.split('\n');
                        
                        for (const line of lines) {
                            if (line.startsWith('data: ')) {
                                try {
                                    // 解析服务器发送的事件流数据
                                    const data = JSON.parse(line.slice(6));
                                    
                                    if (data.type === 'content') {
                                        // 处理摘要内容增量更新
                                        summary += data.content;
                                        // 更新摘要内容，保留关闭按钮
                                        const closeBtn = summaryContent.querySelector('.close-summary-btn');
                                        summaryContent.innerHTML = `
                                            <button class="close-summary-btn" onclick="closeSummary(${articleId})" title="关闭摘要">
                                                <span>×</span>
                                            </button>
                                            <div style="margin-top: 20px;">${summary}</div>
                                        `;
                                        summaryContent.classList.add('show');
                                        // 调整新闻卡片布局以适应摘要内容
                                        const newsCard = summaryContent.closest('.news-card');
                                        if (newsCard) {
                                            newsCard.classList.add('with-summary');
                                        }
                                    } else if (data.type === 'error') {
                                        // 处理生成失败情况
                                        summaryContent.innerHTML = `
                                            <button class="close-summary-btn" onclick="closeSummary(${articleId})" title="关闭摘要">
                                                <span>×</span>
                                            </button>
                                            <div style="margin-top: 20px; color: #dc3545;">生成失败: ${data.error}</div>
                                        `;
                                        summaryContent.classList.add('show');
                                        button.classList.remove('loading');
                                        button.innerHTML = '<span>📝</span>';
                                        return;
                                    } else if (data.type === 'done') {
                                        // 处理摘要生成完成状态
                                        button.classList.remove('loading');
                                        button.innerHTML = '<span>📝</span>';
                                        return;
                                    }
                                } catch (e) {
                                    console.error('解析流数据失败:', e);
                                }
                            }
                        }
                        
                        // 继续读取
                        return readStream();
                    });
                }
                
                return readStream();
            })
            .catch(error => {
                console.error('生成摘要失败:', error);
                summaryContent.innerHTML = `
                    <button class="close-summary-btn" onclick="closeSummary(${articleId})" title="关闭摘要">
                        <span>×</span>
                    </button>
                    <div style="margin-top: 20px; color: #dc3545;">生成摘要失败，请稍后重试</div>
                `;
                summaryContent.classList.add('show');
                button.classList.remove('loading');
                button.innerHTML = '<span>📝</span>';
            });
        }
        
        // 关闭摘要函数
        function closeSummary(articleId) {
            const summaryContent = document.getElementById(`summary-${articleId}`);
            const closeBtn = summaryContent.querySelector('.close-summary-btn');
            const newsCard = summaryContent.closest('.news-card');
            
            // 隐藏摘要内容和关闭按钮
            summaryContent.classList.remove('show');
            summaryContent.innerHTML = `
                <button class="close-summary-btn" onclick="closeSummary(${articleId})" title="关闭摘要" style="display: none;">
                    <span>×</span>
                </button>
            `;
            
            // 移除新闻卡片的摘要样式
            if (newsCard) {
                newsCard.classList.remove('with-summary');
            }
        }
        
        // 首次加载
        fetchNews(1, '', order);
        // v1新增：监听搜索框回车事件
        document.getElementById('search').addEventListener('keydown', function(e) {
            if (e.key === 'Enter') {
                searchNews();
            }
        });
    </script>
</body>
</html>